import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class JsonRefReplacer {

    private final ObjectMapper objectMapper = new ObjectMapper();
    private final JsonNode DEFS;

    // 定义替换的内容
    private final JsonNode languageTagReplacement;
    private final JsonNode marketplaceIdReplacement;

    public JsonRefReplacer(String defsJson) {
        try {
            DEFS = objectMapper.readTree(defsJson);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        this.languageTagReplacement = getLanguageTagReplacement();
        this.marketplaceIdReplacement = getMarketplaceIdReplacement();
    }

    // 获取 "language_tag" 替换内容
    private JsonNode getLanguageTagReplacement() {
        return DEFS.get("language_tag");
    }

    // 获取 "marketplace_id" 替换内容
    private JsonNode getMarketplaceIdReplacement() {
        return DEFS.get("marketplace_id");
    }

    /**
     * 替换 JSON 中的 `properties` 下的 `marketplace_id` 和 `language_tag`，并修改 `hidden` 为 `ui:hidden`
     *
     * @param jsonInput 输入的 JSON 字符串
     * @throws IOException
     */
    public String replaceProperties(String jsonInput) throws IOException {
        JsonNode rootNode = objectMapper.readTree(jsonInput);

        // 递归处理整个 JSON 树
        replacePropertiesRecursively(rootNode);

        // 格式化输出并返回
        return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
    }

    /**
     * 递归查找并替换 `properties` 中的 `marketplace_id` 和 `language_tag`，
     * 同时将 `hidden` 属性更改为 `ui:hidden`
     * <p>
     * @param node 当前处理的 JSON 节点
     */
    private void replacePropertiesRecursively(JsonNode node) {
        // ! 原则上, 我们应该直接适配amazon 提供的json schema 并对amazon json schema自定义的词汇(如: editable, hidden)做支持, 所以不需要在后端处理这些自定义的词汇.
        // ! 现在又要这么做,理由很简单: "适配前端三方组件: vue json schema form".
        // ! vue json schema form(以下简称vjsf) 官网: https://vue-json-schema-form.lljj.me/zh/guide/
        // ! 简介: 支持多种js框架(react, vue2, vue3), 目前选择使用的是支持vue3的 @lljj/vue3-form-element, 其支持直接通过json schema转换为form表单
        if (node == null) {
            return;
        }

        // 如果是对象节点，检查是否包含 properties 字段
        if (node.isObject()) {
            // 如果当前节点包含 properties 字段，处理它
            if (node.has("properties")) {
                JsonNode propertiesNode = node.get("properties");
                if (propertiesNode.isObject()) {
                    // 替换 "marketplace_id" 和 "language_tag"
                    if (propertiesNode.has("marketplace_id")) {
                        ((com.fasterxml.jackson.databind.node.ObjectNode) propertiesNode)
                                .set("marketplace_id", marketplaceIdReplacement);
                    }
                    if (propertiesNode.has("language_tag")) {
                        ((com.fasterxml.jackson.databind.node.ObjectNode) propertiesNode)
                                .set("language_tag", languageTagReplacement);
                    }
                }
            }

            // 递归处理每个字段
            node.fieldNames().forEachRemaining(fieldName -> {
                JsonNode childNode = node.get(fieldName);
                replacePropertiesRecursively(childNode);
            });

            // 查找并替换 hidden 为 ui:hidden
            // ! vjsf对是否隐藏的支持配置为: ui:hidden
            if (node.has("hidden")) {
                JsonNode hiddenNode = node.get("hidden");
                ((com.fasterxml.jackson.databind.node.ObjectNode) node)
                        .set("ui:hidden", hiddenNode);
                // 删除原有的 hidden 属性
                ((com.fasterxml.jackson.databind.node.ObjectNode) node).remove("hidden");
            }
        }

        // 如果是数组节点，递归遍历每个元素
        else if (node.isArray()) {
            for (JsonNode element : node) {
                replacePropertiesRecursively(element);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        // 读取输入的 JSON 文件
        String json = Files.readString(Paths.get("E:\\yanjiu_json_schema\\hardware_clamp_vise.json"));

        // 从 JSON 中提取 $defs 部分
        JsonNode defs = new ObjectMapper().readTree(json).path("$defs");

        // 创建 JsonRefReplacer 实例，传入 $defs 部分
        JsonRefReplacer refReplacer = new JsonRefReplacer(defs.toString());

        // 替换 `properties` 下的 `marketplace_id` 和 `language_tag`
        String result = refReplacer.replaceProperties(json);
        System.out.println(result);
    }
}
